﻿// Copyright (c) 2012 - 2020 Jared Zheng <jaredz at outlook dot com>
// Buddha Framework is licensed under Mulan PSL v2.
// You can use this software according to the terms and conditions of the Mulan PSL v2.
// You may obtain a copy of Mulan PSL v2 at:
//          http://license.coscl.org.cn/MulanPSL2
// THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
// EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
// MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
// See the Mulan PSL v2 for more details.
//
// Create : 2012-12-01 version 0.1 Jared Zheng <jaredz at outlook dot com>
// Update : 2018-12-05 version 3.1.5 Jared Zheng <jaredz at outlook dot com>

#include "stdafx.h"
#include "resource.h"
#include "network.h"
#include "servermap.h"
#include "ServerLoader.h"
#include "BalanceDlg.h"

///////////////////////////////////////////////////////////////////////////////////////////////////////////
// CBalanceDlg
XBEGIN_DLG_ID_WND_EXCHANGE( CBalanceDlg )
XDLG_ID_WND( IDC_CONNECT_CENTER,  m_ConnectCenter )
XDLG_ID_WND( IDC_UDP_EXTERNAL,    m_UDPExternal )
XDLG_ID_WND( IDC_BALANCE_INFO,    m_ServerInfo )
XDLG_ID_WND( IDD_AUTHOR,          m_AuthorSvr )
XEND_DLG_ID_WND_EXCHANGE( CXDlg )

CBalanceDlg::CBalanceDlg(void)
: m_uBalanceAuthor(0)
, m_uBalanceWLAddr(0)
, m_uBalanceLoad(0)
, m_uAuthorCount(0)
, m_uAuthorOnline(0)
, m_uAuthorTotal(0)
{
}

CBalanceDlg::~CBalanceDlg(void)
{
}

LRESULT CBalanceDlg::OnInitDialog(void)
{
    RECT rc;
    GetClientRect(&rc);
    rc.top += (DLG_ITEM_GRAP + DLG_ITEM_GRAP + DLG_ITEM_GRAP + DLG_ITEM_HEIGHT);
    rc.top += (DLG_ITEM_GRAP + DLG_ITEM_GRAP + DLG_ITEM_GRAP + DLG_ITEM_HEIGHT);

    m_AuthorSvr.MoveWindow(0, rc.top, rc.right, (rc.bottom - rc.top));
    //
    CStringFix strTemp;
    strTemp.Load(IDC_CONNECT_CENTER);
    m_ConnectCenter.SetWindowText(*strTemp);

    strTemp.Load(IDC_UDP_EXTERNAL);
    m_UDPExternal.SetWindowText(*strTemp);
    //
    InitServerData(PAKT_AUTHOR);
    return TRUE;
}

LRESULT CBalanceDlg::OnSize(WPARAM, LPARAM lParam, BOOL&)
{
    RECT rc   = { 0 };
    rc.right  = (Long)LOWORD(lParam);
    rc.bottom = (Long)HIWORD(lParam);

    rc.top += (DLG_ITEM_GRAP + DLG_ITEM_GRAP + DLG_ITEM_GRAP + DLG_ITEM_HEIGHT);
    m_ServerInfo.MoveWindow(0, rc.top, rc.right, DLG_ITEM_HEIGHT);

    rc.top += (DLG_ITEM_GRAP + DLG_ITEM_GRAP + DLG_ITEM_GRAP + DLG_ITEM_HEIGHT);
    m_AuthorSvr.MoveWindow(0, rc.top, rc.right, (rc.bottom - rc.top));

    rc.right /=2;
    if (rc.right > DLG_ITEM_WIDTH)
    {
        m_ConnectCenter.MoveWindow(0, 0, (rc.right - DLG_ITEM_GRAP), (DLG_ITEM_GRAP + DLG_ITEM_HEIGHT));
        m_UDPExternal.MoveWindow((rc.right + DLG_ITEM_GRAP), 0, (rc.right - DLG_ITEM_GRAP), (DLG_ITEM_GRAP + DLG_ITEM_HEIGHT));
    }
    return 0;
}

void CBalanceDlg::OnLive(bool bStart)
{
    CStringFix strTemp;
    strTemp.Load(IDC_UDP_EXTERNAL);
    if (bStart)
    {
        CStrAddr strAddr;
        GServerLoaderInst->m_Config.GetServerAddr(CServerConfig::CFG_LOAD_BALANCE, CServerConfig::CFG_LOAD_NONE, strAddr);
        strTemp.AppendFormat(TF("[%s]:%d"), *strAddr.strIp, strAddr.usPort);
        m_UDPExternal.SetWindowText(*strTemp);
    }
    else
    {
        m_UDPExternal.SetWindowText(*strTemp);

        strTemp.Load(IDC_CONNECT_CENTER);
        m_ConnectCenter.SetWindowText(*strTemp);

        m_uBalanceAuthor = 0;
        m_uBalanceWLAddr = 0;
        m_uBalanceLoad   = 0;
        m_uAuthorCount   = 0;
        m_uAuthorOnline  = 0;
        m_uAuthorTotal   = 0;
    }
    m_ServerInfo.SetWindowText(TF(""));
}

void CBalanceDlg::OnLink(Int nServerIndex, uintptr_t utData)
{
    UNREFERENCED_PARAMETER(nServerIndex);
    assert(nServerIndex == PAKT_CENTER);

    CStringFix strTemp;
    strTemp.Load(IDC_CONNECT_CENTER);

    CNetAddr* pAddr = (reinterpret_cast<CNetAddr*>(utData));

    CStrAddr strAddr;
    GServerLoaderInst->m_Config.GetServerAddr(CServerConfig::CFG_LOAD_CENTER, CServerConfig::CFG_LOAD_NONE, strAddr, true);
    strTemp.AppendFormat(TF("[%s]:%d"), *strAddr.strIp, strAddr.usPort);

    GServerLoaderInst->m_NetworkPtr->TranslateAddr(strAddr.strIp, strAddr.usPort, *pAddr, false);
    strTemp.AppendFormat(TF("([%s]:%d)"), *strAddr.strIp, strAddr.usPort);

    m_ConnectCenter.SetWindowText(*strTemp);
}

void CBalanceDlg::OnUpdate(Int, uintptr_t)
{
}

void CBalanceDlg::OnSync(Int nServerIndex, uintptr_t utData)
{
    if (nServerIndex == PAKT_AUTHOR)
    {
        PSERVER_STATUS pStatus = reinterpret_cast<PSERVER_STATUS>(utData);
        m_uAuthorTotal    = pStatus->uTotal;
        m_uAuthorOnline   = pStatus->uOnline;
        m_uAuthorCount    = pStatus->usLoad;
    }
    else
    {
        PSERVER_STATUS pStatus = reinterpret_cast<PSERVER_STATUS>(utData);
        m_uBalanceAuthor  = pStatus->uTotal;
        m_uBalanceWLAddr  = pStatus->uOnline;
        m_uBalanceLoad    = pStatus->usLoad / DATAD_TOPERCENT;
    }
}

void CBalanceDlg::OnSync(Int nServerIndex, CStream& Stream)
{
    assert(nServerIndex == PAKT_AUTHOR);

    SVR_AUTHOR_MAP::SVR_PAIR Pair;
    while (Stream.IsEnd() == false)
    {
        Pair.Serialize(Stream);

        LVFINDINFO find ={0};
        find.flags  = LVFI_PARAM;
        find.lParam = (LPARAM)(Pair.ullKey);
        Int nIndex  = m_AuthorSvr.FindItem(&find);

        if (Pair.Value.usStatus == STATUSU_UNLINK)
        {
            if (nIndex > -1)
            {
                m_AuthorSvr.DeleteItem(nIndex);
            }
        }
        else if ((Pair.Value.usStatus == STATUSU_SYNC) || (Pair.Value.usStatus == STATUSU_LINK))
        {
            if (nIndex > -1)
            {
                UpdateServerData(nServerIndex, reinterpret_cast<uintptr_t>(&Pair));
            }
            else if (Pair.Value.usStatus == STATUSU_LINK)
            {
                AddServerData(nServerIndex, reinterpret_cast<uintptr_t>(&Pair));
            }
        }
    }
}

void CBalanceDlg::OnUnlink(Int nServerIndex, uintptr_t utData)
{
    UNREFERENCED_PARAMETER(utData);
    CStringFix strTemp;
    if (nServerIndex == PAKT_CENTER)
    {
        m_AuthorSvr.DeleteAllItems();
        m_uAuthorCount  = 0;
        m_uAuthorOnline = 0;
        m_uAuthorTotal  = 0;

        strTemp.Load(IDC_CONNECT_CENTER);
        m_ConnectCenter.SetWindowText(*strTemp);

        UpdateServerInfo();
    }
    else
    {
        assert(nServerIndex == PAKT_BALANCE);

        strTemp.Load(IDC_UDP_EXTERNAL);
        m_UDPExternal.SetWindowText(*strTemp);
    }
}

void CBalanceDlg::UpdateServerInfo(void)
{
    CStringFix strInfo;
    strInfo.Load(IDC_BALANCE_INFO);

    CStringFix strTemp;
    strTemp.Format(*strInfo, m_uBalanceAuthor, m_uBalanceWLAddr, m_uBalanceLoad,
                   m_uAuthorCount, m_uAuthorOnline, m_uAuthorTotal);
    m_ServerInfo.SetWindowText(*strTemp);
}

CXListView* CBalanceDlg::GetListView(Int nServerIndex)
{
    UNREFERENCED_PARAMETER(nServerIndex);
    assert(nServerIndex == PAKT_AUTHOR);
    return &m_AuthorSvr;
}

